package com.clusterswisdom.horn.api.tmall.client;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.clusterswisdom.horn.api.tmall.HornTmcClient;
import com.clusterswisdom.horn.api.tmall.config.TmallApplication;
import com.taobao.api.ApiException;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoRequest;
import com.taobao.api.TaobaoResponse;
import com.taobao.api.internal.util.WebUtils;
import com.taobao.api.request.TmcUserPermitRequest;

public class HornTaobaoClient extends DefaultTaobaoClient implements TmClient {

	public static final String REDIRECT_URL = "http://121.41.167.115/horn/defaultToken.jsp";
	
	public static final String TOKEN_URL = "https://oauth.taobao.com/token";
	
	public static final String APP_CODE = "default";
	
	private TmallApplication application;
	
	public HornTaobaoClient(TmallApplication application) {
		super(application.getUrl(), application.getAppKey(), application.getAppSecret());
		this.application = application;
	}
	
	@Override
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public TaobaoResponse execute(TaobaoRequest request, String session) throws ApiException {
		if (!HornTaobaoClient.sessionInvalidate(application)) {
			try {
				session = refreshSession();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return super.execute(request, session);
	}

	@Override
	public TmallApplication getApplication() {
		return application;
	}
	
	@Override
	public String initCode(String code) {
		Map<String, String> props = new HashMap<String, String>();
		props.put("grant_type", "authorization_code");

		props.put("code", code);
		props.put("client_id", application.getAppKey());
		props.put("client_secret", application.getAppSecret());
		props.put("redirect_uri", REDIRECT_URL);
		props.put("view", "web");
		try {
			String jsonString = WebUtils.doPost(TOKEN_URL, props, 30000, 30000);
			JSONObject object = JSON.parseObject(jsonString);
			String token = object.getString("access_token");
			String refresh = object.getString("refresh_token");
			Long invalidateTime = object.getLong("expires_in");
			HornTaobaoClient.initApplication(this, token, refresh, invalidateTime);
			
			return jsonString;

		} catch (IOException e) {
			e.printStackTrace();
			return e.getLocalizedMessage();
			
		}
	}
	
	private String refreshSession() throws IOException {
		Map<String, String> param = new HashMap<String, String>();
		param.put("grant_type", " refresh_token ");
		param.put("refresh_token", application.getRefreshKey());
		param.put("client_id", application.getAppKey());
		param.put("client_secret", application.getAppSecret());
		param.put("view", "web");
			
		String responseJson = WebUtils.doPost(TOKEN_URL, param, 3000, 3000);
		JSONObject object = JSON.parseObject(responseJson);
		String token = object.getString("access_token");
		String refresh = object.getString("refresh_token");
		Long invalidateTime = object.getLong("re_expires_in");
		
		application.setSessionKey(token);
		application.setRefreshKey(refresh);
		application.setInvalidateTime(System.currentTimeMillis() + invalidateTime);
		
		return token;
	}
	
	public static boolean sessionInvalidate(TmallApplication application) {
		if (application.getRefreshKey() == null || application.getInvalidateTime() == null) {
			return true;
		}
		
		return System.currentTimeMillis()  < application.getInvalidateTime();
	}
	
	public static void initApplication(TmClient client, String sessionKey, String refreshSession, Long time) {
		client.getApplication().setSessionKey(sessionKey);
		client.getApplication().setRefreshKey(refreshSession);
		client.getApplication().setInvalidateTime(System.currentTimeMillis() + time);
		storeConfig(client.getApplication());
		
		try {
			if (client.getApplication().isMonitEvent()) {
				client.execute(new TmcUserPermitRequest(), client.getApplication().getSessionKey());
//				new TakeEventThread(client).start();
				HornTmcClient tmcClient = new HornTmcClient(client.getApplication());
				tmcClient.connect();
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			
		}
	}
	
	private static void storeConfig(TmallApplication application) {
		 Properties propertie = new Properties(); 
		 propertie.put("sessionKey", application.getSessionKey());
		 propertie.put("refreshKey", application.getRefreshKey());
		 propertie.put("invalidateTime", application.getInvalidateTime());
		 
		 try {
			propertie.store(new FileOutputStream(new File(application.getName())), "");
			
		}  catch (Exception e) {
			e.printStackTrace();
			
		}
	}
}